using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using System.Windows.Forms;
using BTV.Base;
using System.ComponentModel;

namespace BTV.TVAnyTime
{
    public class TVAnyDataDownloader : BTVDataDownloader
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "ioe"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "e2"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "e")]
        public override void DownloadAllData()
        {
            DateTime now = DateTime.Now;
            String month = now.Month + "";
            if (month.Length < 2)
                month = "0" + month;
            String day = now.Day + "";
            if (day.Length < 2)
                day = "0" + day;
            String date = now.Year + month + day;
            String file = date + ".tar.gz";
            String url = "http://backstage.bbc.co.uk/feeds/tvradio/" + file;
            WebClient c = new WebClient();
            c.Proxy = WebRequest.DefaultWebProxy;
            c.Headers.Add("user-agent", "BTV, http://tv.blueghost.co.uk/pc/ - blueghostuk@gmail.com");
            String dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\btv\\data\\";
            Directory.CreateDirectory(dir);
            if (BackgroundProcess != null){
                BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                bwpb.TitleMessage = "Getting BBC TV Data";
                bwpb.DetailMessage = "Getting data from " + url;
                bwpb.IconType = ToolTipIcon.Info;
                BackgroundProcess.ReportProgress(5, bwpb);
            }
            System.Windows.Forms.Application.DoEvents();
            Console.WriteLine("Getting data file from:" + url);
            /*catch 404 and try previous day*/
            try
            {
                c.DownloadFile(url, dir + file);
            }
            catch 
            {
                Console.WriteLine("Error 404: Trying previous days file");
                //download previous day
                now = DateTime.Now.AddDays(-1);
                month = now.Month + "";
                if ( month.Length < 2 )
                    month = "0" + month;
                day = now.Day + "";
                if ( day.Length < 2 )
                    day = "0" + day;
                date = now.Year + month + day;
                file = date + ".tar.gz";
                url = "http://backstage.bbc.co.uk/feeds/tvradio/" + file;
                Console.WriteLine("Getting data file from:" + url);
                try
                {
                    c.DownloadFile(url, dir + file);
                }
                catch 
                {
                    if (BackgroundProcess != null)
                    {
                        BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                        bwpb.TitleMessage = "Download Incomplete";
                        bwpb.DetailMessage = "There was an error downloading the data file. Please try again later";
                        bwpb.IconType = ToolTipIcon.Error;
                        bwpb.IconDuration = 3000;
                        BackgroundProcess.ReportProgress(100, bwpb);
                    }
                    return;
                }
            }
            if (BackgroundProcess != null)
            {
                BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                bwpb.TitleMessage = "BBC TV Data Download Complete";
                bwpb.DetailMessage = "All Data has been downloaded, it will now be processed";
                bwpb.IconType = ToolTipIcon.Info;
                bwpb.IconDuration = 1000;
                BackgroundProcess.ReportProgress(10, bwpb);
            }
            
            Console.WriteLine("Download Complete!");

            Stream s = new GZipInputStream(File.OpenRead(dir+file));
            FileStream fs = File.Create(dir+Path.GetFileNameWithoutExtension(file));

            if (BackgroundProcess != null)
            {
                BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                bwpb.DetailMessage = "Decompressing Data File";
                BackgroundProcess.ReportProgress(20, bwpb);
            }
            Console.WriteLine("Decompressing " + dir + file + " to " + Path.GetFileNameWithoutExtension(dir + file));
            int size = 2048;
            byte[] writeData = new byte[2048];
            while (true)
            {
                size = s.Read(writeData, 0, size);
                if (size > 0)
                {
                    fs.Write(writeData, 0, size);
                }
                else
                {
                    break;
                }
            }
            s.Close();
            fs.Close();
            Console.WriteLine("Decompressed File");

            Console.WriteLine("Decompressing " + dir + Path.GetFileNameWithoutExtension(dir + file));
            fs = new FileStream(dir + Path.GetFileNameWithoutExtension(file), FileMode.Open);
            TarArchive t = TarArchive.CreateInputTarArchive(fs);
            t.ExtractContents(dir);
            t.CloseArchive();
            fs.Close();
            if (BackgroundProcess != null)
            {
                BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                bwpb.DetailMessage = "Decompressed Data File";
                BackgroundProcess.ReportProgress(30, bwpb);
            }
            Console.WriteLine("Decompressed File");

            File.Delete(dir + file);
            File.Delete(dir + Path.GetFileNameWithoutExtension(file));
            
            /*move all files*/
            if (BackgroundProcess != null)
            {
                BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                bwpb.DetailMessage = "Moving Files";
                BackgroundProcess.ReportProgress(60, bwpb);
            }
            Console.WriteLine("Moving all files");
            DirectoryInfo sd = new DirectoryInfo(dir + date);
            FileInfo[] finfo = sd.GetFiles();
            DateTime previousDate = DateTime.Now.AddDays(-1.0);
            String pd = "" + previousDate.Year + previousDate.Month + previousDate.Day;
            foreach (FileInfo f in finfo)
            {
                if ( f.Name.IndexOf(pd) == -1 )
                {/*don't override previous days data as file is shorter*/
                    try
                    {
                        File.Move(f.FullName, dir + f.Name);
                    }
                    catch 
                    {
                        /*exists*/
                        File.Delete(dir + f.Name);
                        File.Move(f.FullName, dir + f.Name);
                    }
                }
                else
                {
                    File.Delete(f.FullName);
                }
            }
            Console.WriteLine("Move complete");
            try
            {
                Directory.Delete(dir + date);
            }
            catch { }
            if (BackgroundProcess != null)
            {
                BackgroundWorkerPassBack bwpb = new BackgroundWorkerPassBack();
                bwpb.TitleMessage = "BBC TV Data Update Complete";
                bwpb.DetailMessage = "All Data has been downloaded and will now be loaded";
                bwpb.IconType = ToolTipIcon.Info;
                bwpb.IconDuration = 1000;
                BackgroundProcess.ReportProgress(100, bwpb);
            }
        }
    }
}
